package com.spdd.mt.biz.manager.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.spdd.mt.biz.constant.*;
import com.spdd.mt.biz.entity.MtProductEntity;
import com.spdd.mt.biz.entity.MtRechargeOrderEntity;
import com.spdd.mt.biz.entity.MtRechargeOrderPreEntity;
import com.spdd.mt.biz.exception.BusinessException;
import com.spdd.mt.biz.manager.channel.SpddService;
import com.spdd.mt.biz.manager.model.WebResponse;
import com.spdd.mt.biz.manager.model.request.OrderMakeRequest;
import com.spdd.mt.biz.manager.model.request.OrderPreMakeRequest;
import com.spdd.mt.biz.manager.model.request.OrderQueryRequest;
import com.spdd.mt.biz.manager.model.response.OrderMakeResponse;
import com.spdd.mt.biz.manager.model.response.OrderPreMakeResponse;
import com.spdd.mt.biz.manager.model.response.OrderQueryResponse;
import com.spdd.mt.biz.service.MtProductService;
import com.spdd.mt.biz.service.MtRechargeOrderPreService;
import com.spdd.mt.biz.service.MtRechargeOrderService;
import com.spdd.mt.biz.util.StatusUtils;
import com.spdd.mt.common.thread.ThreadPoolTypeEnum;
import com.spdd.mt.common.thread.ThreadService;
import com.spdd.mt.common.util.DateUtils;
import com.spdd.mt.common.util.IDGenerator;
import com.spdd.mt.common.util.JacksonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Objects;

/**
 * 订单相关服务
 *
 * @since 2025年04月04日
 */
@Slf4j
@Service
public class OrderService {

    @Autowired
    private IDGenerator idGenerator;

    @Autowired
    private ThreadService threadService;

    @Autowired
    private SpddService spddService;

    @Autowired
    private MtProductService mtProductService;

    @Autowired
    private MtRechargeOrderService rechargeOrderService;

    @Autowired
    private MtRechargeOrderPreService rechargeOrderPreService;

    // public static final Map<Integer, String> ORDER_STATUS_MAPPING = ImmutableMap.<Integer, String>builder()
    //         .put(OrderStatus.SUCCESS.getValue(), MtOrderStatus.SUCCESS)
    //         .put(OrderStatus.FAILED.getValue(), MtOrderStatus.FAILED)
    //         .put(OrderStatus.PROCESSING.getValue(), MtOrderStatus.IN_PROCESS)
    //         .put(OrderStatus.REEXCHANGE.getValue(), MtOrderStatus.SUCCESS) // 返销按失败返回
    //         .put(OrderStatus.READY.getValue(), MtOrderStatus.IN_PROCESS)
    //         .build();
    //
    // public static final Map<Integer, String> ORDER_CANCEL_STATUS_MAPPING = ImmutableMap.<Integer, String>builder()
    //         .put(OrderStatus.SUCCESS.getValue(), MtOrderStatus.SUCCESS)
    //         .put(OrderStatus.FAILED.getValue(), MtOrderStatus.CANCEL)
    //         .put(OrderStatus.PROCESSING.getValue(), MtOrderStatus.IN_PROCESS)
    //         .put(OrderStatus.REEXCHANGE.getValue(), MtOrderStatus.CANCEL) //  返销按已取消返回
    //         .put(OrderStatus.READY.getValue(), MtOrderStatus.IN_PROCESS) // 返销按失败返回
    //         .build();

    /**
     * 预下单服务处理
     *
     * @param preMakeRequest 预下单参数
     */
    public OrderPreMakeResponse orderPreMake(OrderPreMakeRequest preMakeRequest) {
        // 根据商品编号读取商品充值信息
        MtProductEntity product = mtProductService.getByMerchNoAndProductCode(preMakeRequest.getMerchNo(), preMakeRequest.getProductCode());
        if (Objects.isNull(product)) {
            throw new BusinessException(ResponseCode.BUSINESS_ERROR, "商品不存在");
        }

        try {
            // 构建预下单订单并存储
            MtRechargeOrderPreEntity entity = MtRechargeOrderPreEntity.builder()
                    .merchNo(preMakeRequest.getMerchNo())
                    .account(preMakeRequest.getAccount())
                    .productCode(preMakeRequest.getProductCode())
                    .preOrderNo(idGenerator.newPreOrderId())
                    .build();
            rechargeOrderPreService.save(entity);

            // 请求SPDD预下单服务，查询结果
            MtRechargeOrderPreEntity updateEntity = spddService.orderPreRecharge(entity, product);

            // 更新预下单表
            entity = updatePreOrder(updateEntity, entity);

            log.info("请求SPDD预下单接口返回结果:{}", JacksonUtils.toJson(entity));
            return new OrderPreMakeResponse(entity.getReturnStatus(), entity.getReturnMessage(), entity.getReturnCode());
        } catch (Exception e) {
            log.error("话费订单预下单充值接口异常，error=" + e.getMessage(), e);
            return new OrderPreMakeResponse(MtResponseStatus.INNER_ERROR.getValue(), MtResponseStatus.INNER_ERROR.getDesc(), "Other.Inner");
        }
    }

    /**
     * 充值下单服务处理
     *
     * @param makeRequest 充值订单参数
     */
    public OrderMakeResponse recharge(OrderMakeRequest makeRequest) {
        // 根据商品编号读取商品充值信息
        MtProductEntity product = mtProductService.getByMerchNoAndProductCode(makeRequest.getMerchNo(), makeRequest.getProductCode());
        if (Objects.isNull(product)) {
            throw new BusinessException(ResponseCode.BUSINESS_ERROR, "商品不存在");
        }

        MtRechargeOrderEntity entity = getMtRechargeOrderEntity(makeRequest, product);
        // 保存数据库
        try {
            rechargeOrderService.save(entity, entity.getTradeMonth());
        } catch (DuplicateKeyException dke) {
            // 表示重复下单，保持幂等性，应该直接返回下单成功
            log.info("唯一键冲突, message: {}", dke.getCause().getMessage());

            // 根据美团订单号获取订单数据
            MtRechargeOrderEntity order = rechargeOrderService.getByMtOrderNo(makeRequest.getMtOrderNo());

            if (Objects.nonNull(order)) {
                log.info("返回重复请求的订单信息, tradeOrderNo={}", order.getMtOrderNo());
                return completeResponse(order);
            }
            return (OrderMakeResponse) innerExceptionResponse();
        } catch (Exception e) {
            // 保存订单异常，一般是连接数据库出现了问题，可以直接返回
            log.error("保存订单异常", e);
            return failedResponse(entity);
        }

        // 执行SPDD充值接口，获取数据，如果抛出异常，会触发重试机制
        MtRechargeOrderEntity updateEntity = spddService.orderRecharge(entity, product);

        // 更新订单
        entity = updateOrder(updateEntity, entity);

        // 处理返回数据
        return completeResponse(entity);
    }

    /**
     * 话费订单查询服务
     *
     * @param queryRequest 请求参数
     */
    public OrderQueryResponse query(OrderQueryRequest queryRequest) {
        // 根据美团订单号获取订单数据
        MtRechargeOrderEntity order = rechargeOrderService.getByMtOrderNo(queryRequest.getMtOrderNo());
        if (Objects.isNull(order)) {
            // 查不到订单，返回失败
            log.info("订单不存在，信息 mtOrderNo = {}", queryRequest.getMtOrderNo());
            // return new OrderQueryResponse(WebResponse.fail(MtResponseStatus.QUERY_ORDER_FAIL));
            return completeQueryResponse(null, queryRequest.getMtOrderNo());
        }

        if (OrderStatus.isFinal(order.getOrderStatus())) {
            log.info("查询订单，订单已为终态，直接返回。orderNo={}, mtOrderNo={}, orderStatus={}", order.getOrderNo(), order.getMtOrderNo(), order.getOrderStatus());

            return completeQueryResponse(order, queryRequest.getMtOrderNo());
        }

        log.info("查询订单，订单 {} 非终态，开始查询SPDD服务", order.getOrderNo());
        MtRechargeOrderEntity updateEntity = spddService.orderQuery(order);

        // 更新订单
        order = updateOrder(updateEntity, order);

        // 如果有待重发标记，则重发订单，和定时任务的重发机制可能产生并发问题
        if (ReorderStatus.WAIT.getValue().equals(updateEntity.getReorderStatus())) {

            // 异步提交重新下单
            MtRechargeOrderEntity finalOrder = order;
            threadService.submit(ThreadPoolTypeEnum.COMMON, () -> reorder(finalOrder));

        }

        return completeQueryResponse(order, queryRequest.getMtOrderNo());
    }

    /**
     * 重新下单
     *
     * @param order 订单信息
     */
    public void reorder(MtRechargeOrderEntity order) {
        MtProductEntity product = mtProductService.getByMerchNoAndProductCode(order.getMerchNo(), order.getProductCode());

        // 发之前再进行一次校验，防止并发重复
        if (!ReorderStatus.WAIT.getValue().equals(order.getReorderStatus())) {
            return;
        }

        // 执行SPDD充值接口，获取数据，如果抛出异常，会触发重试机制
        MtRechargeOrderEntity updateEntity = spddService.orderRecharge(order, product);

        // 重发完成后，无论重发结果如何，都更新重发次数和最后重发的时间
        updateEntity.setReorderTimes(order.getReorderTimes() + 1);
        updateEntity.setLastReorderTime(DateUtil.date());
        updateOrder(updateEntity, order);
    }

    // 私有方法

    private MtRechargeOrderEntity getMtRechargeOrderEntity(OrderMakeRequest makeRequest, MtProductEntity product) {
        MtRechargeOrderEntity entity = new MtRechargeOrderEntity();

        entity.setMerchNo(makeRequest.getMerchNo());
        entity.setMtOrderNo(makeRequest.getMtOrderNo());
        entity.setAccount(makeRequest.getAccount());
        entity.setProductCode(makeRequest.getProductCode());
        entity.setProductType(product.getProductType());
        entity.setTimestamp(makeRequest.getTimestamp());
        entity.setNotifyUrl(makeRequest.getNotifyUrl());

        // 美团要求下单成功返回系统订单号，所以这里生成业务订单号
        entity.setOrderNo(idGenerator.newOrderId());
        // entity.setOrderNo(makeRequest.getMtOrderNo());
        entity.setFacePrice(product.getFacePrice());
        entity.setOperator(product.getOperator());
        entity.setProvinceCode(product.getProvinceCode());
        entity.setProvinceName(product.getProvinceName());
        entity.setBuyNum(1);
        entity.setSupplierCode("SPDD");
        entity.setContractPrice(makeRequest.getContractPrice());

        // 设置为待处理状态，SPDD请求成功后，设置为处理中状态
        entity.setOrderStatus(OrderStatus.PROCESSING.getValue());
        entity.setTradeDate(DateUtils.getCurrentDay());
        entity.setTradeMonth(StrUtil.subWithLength(entity.getTradeDate(), 0, 6));
        entity.setStartTime(new Date());
        entity.setOriginOperator(product.getOperator());
        // 默认非携号转网号码，运营商设置一样
        entity.setCurrentOperator(product.getOperator());

        entity.setNotifyStatus(NotifyStatus.INIT.getValue());
        entity.setNotifyTimes(0);
        // 默认无需重发
        entity.setReorderStatus(ReorderStatus.NO.getValue());
        entity.setReorderTimes(0);
        return entity;
    }

    /**
     * 返回内部异常错误
     */
    private WebResponse innerExceptionResponse() {
        return WebResponse.fail(MtResponseStatus.INNER_ERROR);
    }

    /**
     * 返回异常或失败的订单信息
     *
     * @param entity 订单对象
     */
    private OrderMakeResponse failedResponse(MtRechargeOrderEntity entity) {
        return new OrderMakeResponse(WebResponse.fail(MtResponseStatus.MAKE_ORDER_FAIL));
    }

    /**
     * 处理订单返回数据
     *
     * @param entity 订单对象
     */
    private OrderMakeResponse completeResponse(MtRechargeOrderEntity entity) {
        OrderMakeResponse response;

        if (OrderStatus.FAILED.getValue().equals(entity.getOrderStatus())) {
            response = new OrderMakeResponse(WebResponse.fail(entity.getReturnStatus(), entity.getReturnMessage()));
            response.setCode(entity.getReturnCode());
        } else {
            response = new OrderMakeResponse(WebResponse.success(MtResponseStatus.MAKE_ORDER_SUCCESS));
            response.setCode("");
            response.setPartnerOrderNo(entity.getOrderNo());
        }

        return response;
    }

    /**
     * 处理订单返回数据
     *
     * @param entity 订单对象
     */
    private OrderQueryResponse completeQueryResponse(MtRechargeOrderEntity entity, String mtOrderNo) {
        OrderQueryResponse response = new OrderQueryResponse(WebResponse.success(MtResponseStatus.QUERY_ORDER_SUCCESS));

        response.setMtOrderNo(mtOrderNo);
        if (Objects.isNull(entity)) {
            response.setPartnerOrderStatus(MtOrderStatus.ORDER_NOT_EXISTS.getValue());
            return response;
        }

        response.setPartnerOrderNo(entity.getOrderNo());
        response.setFinishTime(DateUtils.formatPureDateTime(entity.getFinishTime()));
        response.setPartnerOrderStatus(StatusUtils.ORDER_STATUS_MT_MAPPER.getOrDefault(
                entity.getOrderStatus(), MtOrderStatus.ORDER_IN_PROCESS).getValue()
        );

        return response;
    }

    private MtRechargeOrderPreEntity updatePreOrder(MtRechargeOrderPreEntity updateEntity, MtRechargeOrderPreEntity originalEntity) {
        log.info("更新预下单表");
        if (Objects.nonNull(updateEntity)) {
            updateEntity.setId(originalEntity.getId());
            rechargeOrderPreService.updateById(updateEntity);

            return rechargeOrderPreService.getById(updateEntity.getId());
        }
        return originalEntity;
    }

    /**
     * 更新数据库，返回最新的订单信息
     *
     * @param updateEntity   更新的对象
     * @param originalEntity 原对象
     */
    private MtRechargeOrderEntity updateOrder(MtRechargeOrderEntity updateEntity, MtRechargeOrderEntity originalEntity) {
        log.info("更新订单表");
        if (Objects.nonNull(updateEntity)) {
            String month = String.valueOf(originalEntity.getTradeMonth());
            rechargeOrderService.updateById(updateEntity, month, originalEntity.getId());
            return rechargeOrderService.getById(month, originalEntity.getId());
        }

        return originalEntity;

        // if (StringUtils.isNotBlank(response.getContractPrice())
        //         && !record.getContractPrice().equals(response.getContractPrice())) {
        //     log.info("更新自己的结算金额");
        //     needUpdate = true;
        //     record.setContractPrice(response.getContractPrice());
        // }
        // if (StringUtils.isBlank(record.getSupplierContractPrice()) || !record.getSupplierContractPrice().equals(response.getSupplierContractPrice())) {
        //     log.info("更新供应商结算金额");
        //     needUpdate = true;
        //     record.setSupplierContractPrice(response.getSupplierContractPrice());
        // }
        // if (StringUtils.isBlank(record.getSupplierOrderNo()) || !record.getSupplierOrderNo().equals(response.getSupplierOrderNo())) {
        //     log.info("更新供应商订单号");
        //     needUpdate = true;
        //     record.setSupplierOrderNo(response.getSupplierOrderNo());
        // }
        // if (StringUtils.isNotBlank(response.getOriginCarrierCode())
        //         && !response.getOriginCarrierCode().equals(record.getOriginCarrierCode())) {
        //     log.info("更新原运营商");
        //     needUpdate = true;
        //     record.setOriginCarrierCode(response.getOriginCarrierCode());
        // }
        // if (StringUtils.isNotBlank(response.getCurrentCarrierCode())
        //         && !response.getCurrentCarrierCode().equals(record.getCurrentCarrierCode())) {
        //     log.info("更新现运营商");
        //     needUpdate = true;
        //     record.setCurrentCarrierCode(response.getCurrentCarrierCode());
        // }
        // if (null != errorCodeEnum && !errorCodeEnum.getCode().equals(record.getReturnCode())) {
        //     log.info("更新返回码");
        //     needUpdate = true;
        //     record.setReturnCode(errorCodeEnum.getCode());
        // }
        // if (null != errorCodeEnum && !errorCodeEnum.getMsg().equals(record.getReturnMessage())) {
        //     log.info("更新返回信息");
        //     needUpdate = true;
        //     record.setReturnMessage(errorCodeEnum.getMsg());
        // }
        // 查询终态后更新数据库
        // if (OrderStatus.isFinal(entity.getOrderStatus())) {
        //     needUpdate = true;
        //     // entity.setOrderStatus(Integer.valueOf(response.getOrderStatus()));
        //     entity.setFinishTime(response.getFinishTime());
        //     entity.setFinishDate(Integer.valueOf(response.getFinishTime().substring(0, 10).replaceAll("-", "")));
        //     // 成功时赋值成功时间
        //     if (OrderStatusEnum.SUCCESS.getCode().equals(response.getOrderStatus())) {
        //         record.setSuccessTime(response.getFinishTime());
        //     }
        // }
        // if (needUpdate) {
        //
        //     mobileRechargeService.updateFinal(month, record);
        // }
    }
}
